package com.zhilianbao.leyaogo.utils;

import com.baidu.location.Address;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.bql.convenientlog.CLog;
import com.bql.utils.CheckUtils;
import com.bql.utils.EventManager;
import com.zhilianbao.leyaogo.app.LeYaoGoApplication;
import com.zhilianbao.leyaogo.events.LeEventCode;

import org.greenrobot.eventbus.EventBus;

/**
 * ClassName: LocationHelper <br>
 * Description: 定位帮助类<br>
 * Author: Cyarie <br>
 * Created: 2016/8/30 17:41 <br>
 * Update Time：<br>
 * Update Description：<br>
 */
public class LocationHelper implements BDLocationListener {

    public static final String TAG = LocationHelper.class.getSimpleName();

    private static LocationHelper sInstance;

    private LocationClient mLocationClient;//定位Client

    private Address mAddress;//地址

    private String city;//所在城市

    private String cityCode;//所在城市Code

    private double latitude;//纬度

    private double longitude;//经度

    private long lastGetLocationTime;//上一次获取定位的时间


    /**
     * 单例
     *
     * @return
     */
    public static LocationHelper getInstance() {
        synchronized (LocationHelper.class) {
            if (sInstance == null) {
                sInstance = new LocationHelper();
            }
        }
        return sInstance;
    }


    /**
     * 获取地址 使用缓存 60s过期
     */
    public void getAddress() {
        getAddress(true, isUseCache());
    }


    /**
     * 获取及时地址 不使用缓存
     */
    public void getInstantAddress() {
        getAddress(true, false);
    }

    /**
     * 获取地址
     *
     * @param isUseGPS   是否使用GPS
     * @param isUseCache 是否使用缓存 60s过期
     */
    public void getAddress(boolean isUseGPS, boolean isUseCache) {
        if (!isUseCache || mAddress == null || CheckUtils.isEmpty(mAddress.city)) {
            getBDLocation(isUseGPS);
            return;
        }
        EventBus.getDefault().post(new EventManager(LeEventCode.MSG_CODE_BAIDU_LOCATION_SUC, city));
    }

    @Override
    public void onReceiveLocation(BDLocation bdLocation) {
        mLocationClient.stop();
        if (bdLocation != null) {
            updateLocation(bdLocation);
        }
    }


    /**
     * 更新定位信息
     * getLocType()
     * 返回值：
     * 61 ： GPS定位结果，GPS定位成功。
     * 62 ： 无法获取有效定位依据，定位失败，请检查运营商网络或者wifi网络是否正常开启，尝试重新请求定位。 <br/>
     * 63 ： 网络异常，没有成功向服务器发起请求，请确认当前测试手机网络是否通畅，尝试重新请求定位。<br/>
     * 65 ： 定位缓存的结果。<br/>
     * 66 ： 离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果。<br/>
     * 67 ： 离线定位失败。通过requestOfflineLocaiton调用时对应的返回结果。<br/>
     * 68 ： 网络连接失败时，查找本地离线定位时对应的返回结果。<br/>
     * 161： 网络定位结果，网络定位定位成功。<br/>
     * 162： 请求串密文解析失败，一般是由于客户端SO文件加载失败造成，请严格参照开发指南或demo开发，放入对应SO文件。<br/>
     * 167： 服务端定位失败，请您检查是否禁用获取位置信息权限，尝试重新请求定位。<br/>
     * 502： key参数错误，请按照说明文档重新申请KEY。<br/>
     * 505： key不存在或者非法，请按照说明文档重新申请KEY。<br/>
     * 601： key服务被开发者自己禁用，请按照说明文档重新申请KEY。<br/>
     * 602： key mcode不匹配，您的ak配置过程中安全码设置有问题，请确保：sha1正确，“;”分号是英文状态；且包名是您当前运行应用的包名，请按照说明文档重新申请KEY。<br/>
     * 501～700：key验证失败，请按照说明文档重新申请KEY。<br/>
     *
     * @param bdLocation
     */
    private void updateLocation(BDLocation bdLocation) {
        CLog.i(TAG, "BDLocation LocType = " + bdLocation.getLocType());
        mAddress = bdLocation.getAddress();
        city = bdLocation.getAddress().city;
        CLog.i(TAG, "BDLocation city = " + city);
        latitude = bdLocation.getLatitude();
        CLog.i(TAG, "BDLocation getLatitude = " + latitude);
        longitude = bdLocation.getLongitude();
        CLog.i(TAG, "BDLocation getLongitude = " + longitude);
        lastGetLocationTime = System.currentTimeMillis();
        if (bdLocation.getLocType() == 161) {
            cityCode = mAddress.cityCode;
            EventBus.getDefault().post(new EventManager(LeEventCode.MSG_CODE_BAIDU_LOCATION_SUC, city));
        } else {
            EventBus.getDefault().post(new EventManager(LeEventCode.MSG_CODE_BAIDU_LOCATION_FAILED, city));
        }

    }

    /**
     * 获取城市代码
     *
     * @return
     */
    public String getCityCode() {
        return cityCode;
    }

    /**
     * 获取百度定位
     *
     * @param isUseGPS 是否使用GPS
     */
    public void getBDLocation(boolean isUseGPS) {
        if (mLocationClient == null) {
            mLocationClient = new LocationClient(LeYaoGoApplication.getContext());
            mLocationClient.registerLocationListener(this);
        }

        LocationClientOption option = new LocationClientOption();
        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
        option.setScanSpan(1000);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        if (isUseGPS) {
            option.setOpenGps(true);//可选，默认false,设置是否使用gps
            //高精度定位模式：这种定位模式下，会同时使用网络定位和GPS定位，优先返回最高精度的定位结果；
            //低功耗定位模式：这种定位模式下，不会使用GPS，只会使用网络定位（Wi-Fi和基站定位）；
            //仅用设备定位模式：这种定位模式下，不需要连接网络，只使用GPS进行定位，这种模式下不支持室内环境的定位。
            option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        } else {
            option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
        }
        mLocationClient.setLocOption(option);//设置定位方式
        mLocationClient.start();//开启定位
    }


    /**
     * 是否使用缓存 60s过期
     *
     * @return
     */
    private boolean isUseCache() {
        if (System.currentTimeMillis() - this.lastGetLocationTime < 60000) {
            return true;
        }
        return false;
    }


}
